package com.scalar.chiptrack.adaptor.oset;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.users.VendorAdaptor;
import com.scalar.chiptrack.users.dao.AdaptorSetUpDAO;
import com.scalar.ScalarException;

import javax.mail.Store;
import javax.mail.Session;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Part;

import java.util.Properties;
import java.io.InputStream;
import java.io.IOException;
import java.io.BufferedInputStream;

/**
 * Created by IntelliJ IDEA.
 * User: Sudhakar
 * Date: Dec 20, 2007
 * Time: 7:56:57 PM
 */
public class OSETPOP3Adaptor extends JobHandler implements AdaptorConstants
{

    private static final String HOST            = "mail.scalarsoft.com";
    private static final String INBOX           = "INBOX";
    private static final String POP_MAIL        = "pop3";
    private static final String SUBJECT         = "Spectra Linear Wip Report";
    public static final String FILE_NAME_WIP    = "PCCWIPSTD1";
    public static final String ADAPTOR_TYPE     = "OSET_ASSY";

    private Logger m_adaptorLogger  = null;
    private String m_dataOutputDir  = null;
    private String m_username       = null;
    private String m_password       = null;
    private int    m_adaptor_id     = -1;
    /**
     *
     * @throws Exception
     */
    public OSETPOP3Adaptor() throws Exception
    {
        try
        {
            VendorAdaptor vendorAdaptor = AdaptorSetUpDAO.getVendorAdaptorDetailsByVendorNameAndLocation(VENDOR_NAME_OSET, WIP_TYPE_ASSEMBLY);

            m_username = vendorAdaptor.getUserId();
            m_password = vendorAdaptor.getPassWord();
            m_dataOutputDir = vendorAdaptor.getOutPutDirectory();

            if (m_dataOutputDir != null)
            {
                if (m_dataOutputDir.endsWith("/") || m_dataOutputDir.endsWith("\\"))
                {
                    m_dataOutputDir = m_dataOutputDir + m_username;
                }
                else
                {
                    m_dataOutputDir = m_dataOutputDir + "/" + m_username;
                }
            }

            AdaptorUtils.makeAllAdaptorDirs(m_dataOutputDir);
            m_adaptorLogger = AdaptorUtils.getAdaptorLogger(m_dataOutputDir, VENDOR_NAME_OSET);
            AdaptorUtils.setLogger( m_adaptorLogger );
        }
        catch (ScalarException se)
        {
            log("ERROR!! ERROR!! ERROR!! Exception while loading OSET Adaptor Username, Password details from database, Exception: " + se);
            throw se;
        }
    }


    //Main Method
    public static void main(String[] args) throws Exception
    {
        new OSETPOP3Adaptor().execute();
    }

    /**
     * @throws Exception
     */
    public void execute() throws Exception
    {
        try
        {
            // Step 1
            // prints the version of Adaptor
            printHeader();

            // Step 2
            // removes the old files out side done directory
            removeOldFiles();

            // Step 3
            // Establish a session
            Session session = createMailSession(POP_MAIL);

            // Step 4
            // Connect to mail store
            Store store = connect(session, HOST, m_username, m_password);

            // Step 5
            // Retrieve latest message
            readLatestMessage(store);

            // Step 6
            // Clean-up
            close(store);

        }
        catch (Exception e)
        {
            System.out.println("Exception while trying to connect and read data from mail.scalarsoft.com site: " + e);
            e.printStackTrace();

            throw e;
        }
    }

    /**
     * Creates and retuns session based on the given protocol
     *
     * @param protocol
     * @return Session
     */
    private Session createMailSession(String protocol)
    {
        Session session = null;

        //Getting the System properties
        Properties sysProperties = System.getProperties();

        //store the protocol pop3
        sysProperties.put("mail.protocol.store", protocol);

        //Get the Default session Object
        session = Session.getDefaultInstance(sysProperties, null);

        session.setDebug(false);

        return session;
    }

    /**
     * Retrives a store based on the session and authenticates to it
     * Store is returned back
     *
     * @param session
     * @param hostname
     * @param username
     * @param password
     * @return
     * @throws Exception
     */
    private Store connect(Session session, String hostname, String username, String password) throws Exception
    {
        //Get the Store Object that user's desired store protocol.
        //If appropriate store object is not obtained, No SuchProvider Exception is Thrown
        Store store = session.getStore(POP_MAIL);

        //Connects the Mail Server
        store.connect(hostname, username, password);
        log("Successfully logged in to " + hostname);
        System.out.println("Successfully logged in to " + hostname + "\n");

        return store;
    }

    /**
     * @param store
     * @throws Exception
     */
    private void readLatestMessage(Store store) throws Exception
    {
        Folder folder = store.getDefaultFolder();
        if (folder == null)
        {
            throw new ScalarException("No default mail folder");
        }
        //Get the Inbox folder
        folder = folder.getFolder(INBOX);
        if (folder == null)
        {
            throw new ScalarException("Unable to get folder: " + folder);
        }
        //Opens the folder and set the field to read write mode
        folder.open(Folder.READ_WRITE);

        //Get the Messages
        Message[] message = folder.getMessages();
        Message tempMessage = null;

        /*To download Wip sheet */
        for (int i = 0; i < message.length; i++)
        {
            //To get the only Legend Silicon daily report with subject
            if (message[i].getSubject().startsWith(SUBJECT))
            {
                if (tempMessage == null)
                {
                    tempMessage = message[i];
                }
                else
                {
                    java.util.Date date1 = tempMessage.getSentDate();
                    java.util.Date date2 = message[i].getSentDate();
                    if (date1 != null && date2 != null)
                    {
                        if (date2.compareTo(date1) > 0)
                        {
                            tempMessage = message[i];
                        }
                    }
                }
            }
        }
        // To process the Message and download the Wip file
        if (tempMessage != null)
        {
            processMessage(tempMessage);
            tempMessage = null;
        }
    }

    /**
     * @param store
     * @throws Exception
     */
    private void close(Store store) throws Exception
    {
        // Close connection
        store.close();

        System.out.println("Successfully logged out from mail Site ");
        log("Successfully logged out from mail Site ");
    }


    /**
     * To load the Wip sheet
     * and save the File in to out side the Done Directory
     *
     * @param message
     * @throws Exception
     */
    public void processMessage(Message message) throws Exception
    {
        if (message == null)
        {
            return;
        }

        Multipart mp            = null;
        Part part               = null;
        String disposition      = null;
        InputStream inputStream = null;

        log("Processing  Message for OSET WIP info...... ");
        System.out.println("Processing  Message for OSET WIP info.......");

        try
        {
            mp = (Multipart) message.getContent();

            log("\tDownloding  OSET WIP info.................. ");
            System.out.println("\tDownloding  OSET WIP info................. ");

            for (int i = 0; i < mp.getCount(); i++)
            {
                part = mp.getBodyPart(i);
                disposition = part.getDisposition();

                //taking the wip attachment
                if ((disposition != null) && (disposition.equals(Part.ATTACHMENT)))
                {
                    inputStream = part.getInputStream();
                    saveWipFile(FILE_NAME_WIP, inputStream);
                }
            }
        }
        catch (Exception e)
        {
            System.out.println("EXception Occcuered while Proceessing the Messge:" + e);
            e.printStackTrace();
            throw e;
        }

        finally
        {
            if (inputStream != null)
            {
                try
                {
                    inputStream.close();
                    inputStream = null;
                }
                catch (IOException e) {
                }
            }
        }
    }


    /**
     * To Save the Wip Sheet
     *
     * @param fileName
     * @param inputStream
     * @throws Exception
     */
    private void saveWipFile(String fileName, InputStream inputStream) throws Exception
    {
        BufferedInputStream bfReader = null;
        try
        {
            bfReader = new BufferedInputStream(inputStream);
            AdaptorUtils.saveAsBinaryFile(bfReader, m_dataOutputDir, fileName, AdaptorUtils.FILE_EXTN_XLS, true /* append time stamp */);
        }
        catch (ScalarException se)
        {
            System.out.println("Exception While saving the file" + se);
            throw se;
        }
        finally
        {
            if (bfReader != null)
            {
                try
                {
                    bfReader.close();
                    bfReader = null;
                }
                catch (IOException ignore) {
                }
            }
        }
        System.out.println("Done\n");
        log("Done\n");
    }

    /**
     * @param message
     */
    private void log(String message)
    {
        if (message == null) return;

        if (m_adaptorLogger != null)
        {
            synchronized (m_adaptorLogger)
            {
                m_adaptorLogger.logDebug(message + LINE_SEPARATOR);
            }
        }
        else
        {
            System.out.println(message);
        }
    }

    /**
     * Removes older files
     *
     * @throws ScalarException
     */
    private void removeOldFiles() throws ScalarException
    {
        try
        {
            AdaptorUtils.removeOldFiles(m_dataOutputDir, m_adaptorLogger);
        }
        catch (ScalarException se)
        {
            log("Exception occurred while deleting old files at Adaptor Directory");
            throw se;
        }
    }

    /**
     *
     */
    private void printHeader()
    {

        String message = "\n\n+----------- Running OSET POP3 Adaptor on " + new java.util.Date(System.currentTimeMillis()) + " -------------+\n" +
                "\n+---------------------------------------------------------------+\n" +
                "+                                                                \n" +
                "+                        OSET POP3 Adaptor - Beta                 \n" +
                "+                                                                \n" +
                "+    Copy Right (C) 2007 - ScalarSoft Inc., All rights reserved.  \n" +
                "+                                                                \n" +
                "+---------------------------------------------------------------+\n";
        System.out.println(message);
        log(message);
    }

}
